﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Runtime.CompilerServices;

namespace General
{
    /// <summary>
    /// Beinhaltet Methoden um threadübergreifende Aufrufe einfach zu gewährleisten.
    /// ACHTUNG: Diese sind mit Vorsicht zu genießen, da sie ggf. Deadlocks verusachen können!
    /// </summary>
    public class CrossThreading
    {
        delegate void ActionAsyncCallback(System.Windows.Forms.Control control);
        delegate void StringAsyncCallback(System.Windows.Forms.Control control, string text);
        delegate void IntAsyncCallback(System.Windows.Forms.Control control, int number);
        delegate void BooleanAsyncCallback(System.Windows.Forms.Control control, bool boolean);
        delegate void ColorAsyncCallback(System.Windows.Forms.Control control, System.Drawing.Color color);

        // Specific
        delegate void ProgressBarIntAsyncCallback(System.Windows.Forms.ProgressBar control, int number);
        delegate DialogResult MessageBoxCommonAsyncCallback(System.Windows.Forms.Form form, string text, string title, MessageBoxButtons buttons, MessageBoxIcon icon);

        private static void SetTextAsyncFunc(System.Windows.Forms.Control control, string text) { control.Text = text; }
        private static void SetEnabledAsyncFunc(System.Windows.Forms.Control control, bool boolean) { control.Enabled = boolean; }
        private static void SetVisibileAsyncFunc(System.Windows.Forms.Control control, bool boolean) { control.Visible = boolean; }
        private static void SetForeColorAsyncFunc(System.Windows.Forms.Control control, System.Drawing.Color color) { control.ForeColor = color; }
        private static void RefreshAsyncFunc(System.Windows.Forms.Control control) { control.Refresh(); }
        private static void SendToBackAsyncFunc(System.Windows.Forms.Control control) { control.SendToBack(); }
        private static void BringToFrontAsyncFunc(System.Windows.Forms.Control control) { control.BringToFront(); }
        private static void InvalidateAsyncFunc(System.Windows.Forms.Control control) { control.Invalidate(); }        

        // Specific
        private static void SetValueAsyncFunc(System.Windows.Forms.ProgressBar control, int number) { control.Value = number; }
        private static void SetMaximumAsyncFunc(System.Windows.Forms.ProgressBar control, int number) { control.Maximum = number; }
        private static DialogResult MessageBoxShowAsyncFunc(System.Windows.Forms.Form form, string text, string title, MessageBoxButtons buttons, MessageBoxIcon icon) { return MessageBox.Show(form, text, title, buttons, icon); }

        /// <summary>
        /// Setzt asynchron den Text eines spezifischen Controls.
        /// </summary>
        /// <param name="form">Das Form des Controls</param>
        /// <param name="control">Das Control selbst.</param>
        /// <param name="text">Der zu setzende Text.</param>
        public static void SetText(System.Windows.Forms.Form form, System.Windows.Forms.Control control, string text)
        {
            try
            {
                form.Invoke(
                    new StringAsyncCallback(SetTextAsyncFunc),
                    new object[] { control, text }
                );
            }
            catch { }
        }

        /// <summary>
        /// Setzt asynchron die Verfügbarkeit eines spezifischen Controls.
        /// </summary>
        /// <param name="form">Das Form des Controls</param>
        /// <param name="control">Das Control selbst.</param>
        /// <param name="boolean">Der zu setzende Wert.</param>
        public static void SetEnabled(System.Windows.Forms.Form form, System.Windows.Forms.Control control, bool boolean)
        {
            try
            {
                form.Invoke(
                    new BooleanAsyncCallback(SetEnabledAsyncFunc),
                    new object[] { control, boolean }
                );
            }
            catch { }
        }

        /// <summary>
        /// Setzt asynchron die Sichtbarkeit eines spezifischen Controls.
        /// </summary>
        /// <param name="form">Das Form des Controls</param>
        /// <param name="control">Das Control selbst.</param>
        /// <param name="boolean">Der zu setzende Wert.</param>
        public static void SetVisibile(System.Windows.Forms.Form form, System.Windows.Forms.Control control, bool boolean)
        {
            try
            {
                form.Invoke(
                    new BooleanAsyncCallback(SetVisibileAsyncFunc),
                    new object[] { control, boolean }
                );
            }
            catch { }
        }

        /// <summary>
        /// Setzt asynchron die Vordergrundfarbe eines spezifischen Controls.
        /// </summary>
        /// <param name="form">Das Form des Controls</param>
        /// <param name="control">Das Control selbst.</param>
        /// <param name="color">Die zu setzende Farbe.</param>
        public static void SetForeColor(System.Windows.Forms.Form form, System.Windows.Forms.Control control, System.Drawing.Color color)
        {
            try
            {
                form.Invoke(
                    new ColorAsyncCallback(SetForeColorAsyncFunc),
                    new object[] { control, color }
                );
            }
            catch { }
        }

        /// <summary>
        /// Aktualisiert ein spezifisches Control.
        /// </summary>
        /// <param name="form">Das Form des Controls</param>
        /// <param name="control">Das Control selbst.</param>
        public static void Refresh(System.Windows.Forms.Form form, System.Windows.Forms.Control control)
        {
            try
            {
                form.Invoke(
                    new ActionAsyncCallback(RefreshAsyncFunc),
                    new object[] { control }
                );
            }
            catch { }
        }

        /// <summary>
        /// Sendet ein spezifisches Control nach Hinten.
        /// </summary>
        /// <param name="form">Das Form des Controls</param>
        /// <param name="control">Das Control selbst.</param>
        public static void SendToBack(System.Windows.Forms.Form form, System.Windows.Forms.Control control)
        {
            try
            {
                form.Invoke(
                    new ActionAsyncCallback(SendToBackAsyncFunc),
                    new object[] { control }
                );
            }
            catch { }
        }

        /// <summary>
        /// Sendet ein spezifisches Control nach Vorne.
        /// </summary>
        /// <param name="form">Das Form des Controls</param>
        /// <param name="control">Das Control selbst.</param>
        public static void BringToFront(System.Windows.Forms.Form form, System.Windows.Forms.Control control)
        {
            try
            {
                form.Invoke(
                    new ActionAsyncCallback(BringToFrontAsyncFunc),
                    new object[] { control }
                );
            }
            catch { }
        }

        /// <summary>
        /// Invalidiert ein spezifisches Control.
        /// </summary>
        /// <param name="form">Das Form des Controls</param>
        /// <param name="control">Das Control selbst.</param>
        public static void Invalidate(System.Windows.Forms.Form form, System.Windows.Forms.Control control)
        {
            try
            {
                form.Invoke(
                    new ActionAsyncCallback(InvalidateAsyncFunc),
                    new object[] { control }
                );
            }
            catch { }
        }

        #region Progressbar
        /// <summary>
        /// Setzt asynchron den Text eines spezifischen Controls.
        /// </summary>
        /// <param name="form">Das Form des Controls</param>
        /// <param name="control">Das Control selbst.</param>
        /// <param name="number">Der zu setzende Wert.</param>
        public static void SetValue(System.Windows.Forms.Form form, System.Windows.Forms.ProgressBar control, int number)
        {
            number = Math.Max(control.Minimum, Math.Min(number, control.Maximum));
            try
            {
                form.Invoke(
                    new ProgressBarIntAsyncCallback(SetValueAsyncFunc),
                    new object[] { control, number }
                );
            }
            catch { }
        }

        /// <summary>
        /// Setzt asynchron den Text eines spezifischen Controls.
        /// </summary>
        /// <param name="form">Das Form des Controls</param>
        /// <param name="control">Das Control selbst.</param>
        /// <param name="number">Der zu setzende Wert.</param>
        public static void SetMaximum(System.Windows.Forms.Form form, System.Windows.Forms.ProgressBar control, int number)
        {
            try
            {
                form.Invoke(
                    new ProgressBarIntAsyncCallback(SetMaximumAsyncFunc),
                    new object[] { control, number }
                );
            }
            catch { }
        }

        /// <summary>
        /// Öffnet asynchron eine Messagebox.
        /// </summary>
        /// <param name="form">Das zugehörige Formular.</param>
        /// <param name="text">Der enthaltene Text.</param>
        /// <param name="title">Der Titel der Box.</param>
        /// <param name="buttons">Die Schaltflächen der Box.</param>
        /// <param name="icon">Das Icon der Box.</param>
        /// <returns>Das Ergebnis der Box.</returns>
        public static DialogResult MessageBoxShow(System.Windows.Forms.Form form, string text, string title, MessageBoxButtons buttons, MessageBoxIcon icon)
        {
            try
            {
                return (DialogResult)form.Invoke(
                    new MessageBoxCommonAsyncCallback(MessageBoxShowAsyncFunc),
                    new object[] { form, text, title, buttons, icon }
                );
            }
            catch { }
            throw new Exception("No results returned.");
        }
        #endregion Progressbar
    }
}
